﻿using Abide_AddOn_API.Interfaces;
using Abide_Halo_Library;
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace Abide_AddOn_API.Controls
{
    /// <summary>
    /// Provides an empty Tool Abide AddOn.
    /// </summary>
    [ToolboxItem(false), ComVisible(true)]
    public partial class Tool : UserControl, ITool
    {
        private event EventHandler initialize;
        private event EventHandler xboxChanged;
        private event EventHandler indexEntryChanged;
        private event EventHandler nameChanged;
        private event EventHandler descriptionChanged;
        private event EventHandler iconChanged;
        
        /// <summary>
        /// Occurs when the AddOn's name is changed.
        /// </summary>
        [Browsable(true), Category("Property Changed"), Description("Occurs when the tool's name is changed.")]
        public new event EventHandler TextChanged
        {
            add { nameChanged += value; }
            remove { nameChanged -= value; }
        }
        /// <summary>
        /// Occurs when the AddOn's description is changed.
        /// </summary>
        [Browsable(true), Category("Property Changed"), Description("Occurs when the tool's description is changed.")]
        public event EventHandler DescriptionChanged
        {
            add { descriptionChanged += value; }
            remove { descriptionChanged -= value; }
        }
        /// <summary>
        /// Occurs when the AddOn's icon is changed.
        /// </summary>
        [Browsable(true), Category("Property Changed"), Description("Occurs when the tool's icon is changed.")]
        public event EventHandler IconChanged
        {
            add { iconChanged += value; }
            remove { iconChanged -= value; }
        }
        /// <summary>
        /// Occurs when the AddOn is initialized by the host.
        /// </summary>
        [Browsable(true), Category("API Events"), Description("Occurs when the AddOn is initialized by the host.")]
        public event EventHandler Initialize
        {
            add { initialize += value; }
            remove { initialize -= value; }
        }
        /// <summary>
        /// Occurs when the Debug Xbox is changed by the Host.
        /// </summary>
        [Browsable(true), Category("API Events"), Description("Occurs when the Debug Xbox is changed by the Host.")]
        public event EventHandler XboxChanged
        {
            add { xboxChanged += value; }
            remove { xboxChanged -= value; }
        }
        /// <summary>
        /// Occurs when the Selected Index Entry is changed by the Host.
        /// </summary>
        [Browsable(true), Category("API Events"), Description("Occurs when the Selected Index Entry is changed by the Host.")]
        public event EventHandler IndexEntryChanged
        {
            add { indexEntryChanged += value; }
            remove { indexEntryChanged -= value; }
        }
        /// <summary>
        /// Gets and sets the display name of the AddOn.
        /// </summary>
        [Browsable(true), Category("Appearance"), Description("The display name of the AddOn.")]
        public string DisplayName
        {
            get { return name; }
            set
            {
                bool trigger = name != value;
                name = value;
                if (trigger)
                {
                    nameChanged?.Invoke(this, new EventArgs());
                    OnTextChanged(new EventArgs());
                }
            }
        }
        /// <summary>
        /// Gets and sets the description of the AddOn.
        /// </summary>
        [Browsable(true), Category("Abide AddOn Properties"), Description("The description of the AddOn.")]
        public string Description
        {
            get { return description; }
            set
            {
                bool trigger = description != value;
                description = value;
                if (trigger)
                {
                    descriptionChanged?.Invoke(this, new EventArgs());
                    OnDescriptionChanged(new EventArgs());
                }
            }
        }
        /// <summary>
        /// Gets and sets the display icon of the AddOn.
        /// </summary>
        [Browsable(true), Category("Appearance"), Description("The display icon of the AddOn.")]
        public Image Icon
        {
            get { return icon; }
            set
            {
                bool trigger = icon != value;
                icon = value;
                if (trigger)
                {
                    iconChanged?.Invoke(this, new EventArgs());
                    OnIconChanged(new EventArgs());
                }
            }
        }
        /// <summary>
        /// Gets and sets the version of the AddOn.
        /// </summary>
        [Browsable(true), Category("Abide AddOn Properties"), Description("The version of the AddOn.")]
        [TypeConverter(typeof(Design.VersionTypeConverter))]
        public Version Version
        {
            get { return version; }
            set { version = value; }
        }
        /// <summary>
        /// Gets and sets the Abide version this AddOn is designed to work with.
        /// </summary>
        [Browsable(true), Category("Abide AddOn Properties"), Description("The Abide version this AddOn is designed to work with.")]
        [TypeConverter(typeof(Design.VersionTypeConverter))]
        public Version AbideVersion
        {
            get { return abideVersion; }
            set { abideVersion = value; }
        }
        /// <summary>
        /// Gets and sets the author of this AddOn.
        /// </summary>
        [Browsable(true), Category("Abide AddOn Properties"), Description("The author of this AddOn.")]
        public string Author
        {
            get { return author; }
            set { author = value; }
        }
        /// <summary>
        /// Gets and sets the Halo Map Version that this AddOn is designed to work with.
        /// </summary>
        [Browsable(true), Category("Abide AddOn Properties"), Description("The Halo Map Version that this AddOn is designed to work with.")]
        public MapVersion HaloMapVersion
        {
            get { return mapVersion; }
            set { mapVersion = value; }
        }
        /// <summary>
        /// Gets and returns the Abide_AddOn_API.AddOnAPI instance used by this AddOn.
        /// </summary>
        [Browsable(false)]
        public AddOnAPI API
        {
            get { return api; }
        }

        private string name = "Tool";
        private string description = string.Empty;
        private Image icon = null;
        private AddOnAPI api = null;
        private Version abideVersion = AddOnAPI.GetAbideVersion();
        private Version version = new Version(1, 0);
        private string author = "Abide";
        private string directory = string.Empty;
        private MapVersion mapVersion = MapVersion.Halo_2;

        event EventHandler ITool.NameChanged
        {
            add { nameChanged += value; }
            remove { nameChanged -= value; }
        }
        event EventHandler ITool.DescriptionChanged
        {
            add { descriptionChanged += value; }
            remove { descriptionChanged -= value; }
        }
        event EventHandler ITool.IconChanged
        {
            add { iconChanged += value; }
            remove { iconChanged -= value; }
        }
        string ITool.Name
        {
            get { return name; }
        }
        string ITool.Description
        {
            get { return description; }
        }
        Image ITool.Icon
        {
            get { return icon; }
        }
        UserControl ITool.Interface
        {
            get { return this; }
        }
        AddOnAPI IAddOn.API
        {
            get { return api; }
        }
        Version IAddOn.Version
        {
            get { return version; }
        }
        Version IAddOn.AbideVersion
        {
            get { return abideVersion; }
        }
        string IAddOn.Author
        {
            get { return author; }
        }
        string IAddOn.Directory
        {
            get { return directory; }
            set { directory = value; }
        }
        MapVersion IAddOn.MapVersion
        {
            get { return mapVersion; }
        }

        protected Tool() { }
        protected override void OnTextChanged(EventArgs e)
        {
            base.OnTextChanged(e);
        }
        protected virtual void OnDescriptionChanged(EventArgs e) { }
        protected virtual void OnIconChanged(EventArgs e) { }
        protected virtual void OnInitialize(IAddOnHost host)
        {
            //Initialize API
            api = new AddOnAPI(host, this);

            //Throw Event
            if (initialize != null)
                initialize(this, new EventArgs());
        }
        protected virtual void OnXboxChanged(EventArgs e)
        {
            //Throw Event
            if (xboxChanged != null)
                xboxChanged(this, new EventArgs());
        }
        protected virtual void OnIndexEntryChanged(EventArgs e)
        {
            //Throw Event
            if (indexEntryChanged != null)
                indexEntryChanged(this, new EventArgs());
        }
        void IAddOn.Initialize(IAddOnHost host)
        {
            //Virtual Void
            OnInitialize(host);

            //Throw Event
            if (initialize != null)
                initialize(this, new EventArgs());
        }
        void IAddOn.OnXboxChanged()
        {
            //Virtual Void
            OnXboxChanged(new EventArgs());
        }
        void IAddOn.OnIndexEntryChanged()
        {
            //Virtual Void
            OnIndexEntryChanged(new EventArgs());
        }
        void IDisposable.Dispose()
        {
            //Base Dispose
            base.Dispose();
        }
    }
}
